"""
带外管理主界面
"""

import logging
from typing import Dict, Any, List
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QGridLayout,
    QTableWidget, QTableWidgetItem, QHeaderView,
    QPushButton, QLabel, QLineEdit, QComboBox,
    QGroupBox, QSplitter, QTextEdit, QMessageBox,
    QProgressBar, QFrame, QTabWidget
)
from PyQt5.QtCore import Qt, pyqtSignal, QTimer
from PyQt5.QtGui import QFont, QColor

try:
    from src.app.modules.oob.service import OobService
    from src.app.modules.oob.ui.oob_dialog import OobDialog
    from src.app.modules.oob.utils import OobUtils
except ImportError:
    # 尝试相对导入
    try:
        from ..service import OobService
        from .oob_dialog import OobDialog
        from ..utils import OobUtils
    except ImportError as e:
        logger.error(f"导入带外管理模块依赖失败: {e}")
        raise

logger = logging.getLogger(__name__)

class OobWidget(QWidget):
    """带外管理主界面"""
    
    # 信号定义
    status_message = pyqtSignal(str)
    
    def __init__(self, parent=None):
        super().__init__(parent)
        self.oob_service = OobService()
        self.oob_utils = OobUtils()
        self.current_oobs = []
        self._load_retry_count = 0  # 添加重试计数器
        self._max_retries = 10  # 最大重试次数
        
        # 初始化UI
        self.init_ui()
        
        # 设置定时刷新
        self.refresh_timer = QTimer()
        self.refresh_timer.timeout.connect(self.refresh_statistics)
        self.refresh_timer.start(30000)  # 30秒刷新一次
        
        # 使用QTimer.singleShot确保在UI完全初始化后再加载数据
        QTimer.singleShot(100, self.load_oobs)
    
    def init_ui(self):
        """初始化UI界面"""
        layout = QVBoxLayout(self)
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)
        
        # 创建主分割器
        main_splitter = QSplitter(Qt.Vertical)
        layout.addWidget(main_splitter)
        
        # 上部分：统计信息和筛选
        top_widget = self.create_top_widget()
        main_splitter.addWidget(top_widget)
        
        # 下部分：列表和详情
        bottom_widget = self.create_bottom_widget()
        main_splitter.addWidget(bottom_widget)
        
        # 设置分割器比例
        main_splitter.setSizes([200, 500])
        main_splitter.setChildrenCollapsible(False)
    
    def create_top_widget(self):
        """创建上部分组件"""
        top_widget = QWidget()
        top_layout = QVBoxLayout(top_widget)
        top_layout.setContentsMargins(0, 0, 0, 0)
        top_layout.setSpacing(10)
        
        # 统计信息组
        stats_group = self.create_statistics_group()
        top_layout.addWidget(stats_group)
        
        # 筛选条件组
        filter_group = self.create_filter_group()
        top_layout.addWidget(filter_group)
        
        return top_widget
    
    def create_statistics_group(self):
        """创建统计信息组"""
        stats_group = QGroupBox("模块统计")
        stats_layout = QGridLayout(stats_group)
        
        # 总数统计
        stats_layout.addWidget(QLabel("总数:"), 0, 0)
        self.total_count_label = QLabel("0")
        self.total_count_label.setStyleSheet(
            "font-size: 24px; font-weight: bold; color: #2196F3;"
        )
        stats_layout.addWidget(self.total_count_label, 0, 1)
        
        # 按类型统计
        stats_layout.addWidget(QLabel("iDRAC:"), 0, 2)
        self.idrac_count_label = QLabel("0")
        self.idrac_count_label.setStyleSheet(
            "font-size: 18px; font-weight: bold; color: #4CAF50;"
        )
        stats_layout.addWidget(self.idrac_count_label, 0, 3)
        
        stats_layout.addWidget(QLabel("iLO:"), 1, 0)
        self.ilo_count_label = QLabel("0")
        self.ilo_count_label.setStyleSheet(
            "font-size: 18px; font-weight: bold; color: #FF9800;"
        )
        stats_layout.addWidget(self.ilo_count_label, 1, 1)
        
        stats_layout.addWidget(QLabel("其他:"), 1, 2)
        self.other_count_label = QLabel("0")
        self.other_count_label.setStyleSheet(
            "font-size: 18px; font-weight: bold; color: #9C27B0;"
        )
        stats_layout.addWidget(self.other_count_label, 1, 3)
        
        # IP绑定统计
        stats_layout.addWidget(QLabel("已绑定IP:"), 2, 0)
        self.ip_binding_count_label = QLabel("0")
        self.ip_binding_count_label.setStyleSheet(
            "font-size: 18px; font-weight: bold; color: #F44336;"
        )
        stats_layout.addWidget(self.ip_binding_count_label, 2, 1)
        
        return stats_group
    
    def create_filter_group(self):
        """创建筛选条件组"""
        filter_group = QGroupBox("筛选条件")
        filter_layout = QGridLayout(filter_group)
        
        # 筛选字段
        filter_layout.addWidget(QLabel("筛选字段:"), 0, 0)
        self.filter_combo = QComboBox()
        self.filter_combo.addItems([
            "全部", "带外类型", "设备资产", "登录URL"
        ])
        self.filter_combo.currentTextChanged.connect(self.on_filter_changed)
        filter_layout.addWidget(self.filter_combo, 0, 1)
        
        # 筛选值
        filter_layout.addWidget(QLabel("筛选值:"), 0, 2)
        self.filter_value_combo = QComboBox()
        self.filter_value_combo.setEditable(True)
        self.filter_value_combo.currentTextChanged.connect(self.apply_filter)
        filter_layout.addWidget(self.filter_value_combo, 0, 3)
        
        # 搜索框
        filter_layout.addWidget(QLabel("搜索:"), 1, 0)
        self.search_edit = QLineEdit()
        self.search_edit.setPlaceholderText("输入关键词搜索...")
        self.search_edit.textChanged.connect(self.on_search_changed)
        filter_layout.addWidget(self.search_edit, 1, 1, 1, 2)
        
        # 操作按钮
        button_layout = QHBoxLayout()
        
        self.refresh_button = QPushButton("刷新")
        self.refresh_button.clicked.connect(self.load_oobs)
        button_layout.addWidget(self.refresh_button)
        
        self.export_button = QPushButton("导出")
        self.export_button.clicked.connect(self.export_data)
        button_layout.addWidget(self.export_button)
        
        filter_layout.addLayout(button_layout, 1, 3)
        
        return filter_group
    
    def create_bottom_widget(self):
        """创建下部分组件"""
        bottom_widget = QWidget()
        bottom_layout = QHBoxLayout(bottom_widget)
        bottom_layout.setContentsMargins(0, 0, 0, 0)
        bottom_layout.setSpacing(10)
        
        # 创建分割器
        splitter = QSplitter(Qt.Horizontal)
        bottom_layout.addWidget(splitter)
        
        # 左侧：数据列表
        list_widget = self.create_list_widget()
        splitter.addWidget(list_widget)
        
        # 右侧：详情面板
        detail_widget = self.create_detail_widget()
        splitter.addWidget(detail_widget)
        
        # 设置分割器比例
        splitter.setSizes([600, 400])
        splitter.setChildrenCollapsible(False)
        
        return bottom_widget
    
    def create_list_widget(self):
        """创建数据列表组件"""
        list_widget = QWidget()
        list_layout = QVBoxLayout(list_widget)
        list_layout.setContentsMargins(0, 0, 0, 0)
        list_layout.setSpacing(10)
        
        # 标题和操作按钮
        title_layout = QHBoxLayout()
        
        title_label = QLabel("带外管理列表")
        title_font = QFont()
        title_font.setBold(True)
        title_font.setPointSize(12)
        title_label.setFont(title_font)
        title_layout.addWidget(title_label)
        
        title_layout.addStretch()
        
        self.add_button = QPushButton("新增带外管理")
        self.add_button.clicked.connect(self.add_oob)
        title_layout.addWidget(self.add_button)
        
        self.edit_button = QPushButton("编辑")
        self.edit_button.clicked.connect(self.edit_oob)
        self.edit_button.setEnabled(False)
        title_layout.addWidget(self.edit_button)
        
        self.delete_button = QPushButton("删除")
        self.delete_button.clicked.connect(self.delete_oob)
        self.delete_button.setEnabled(False)
        title_layout.addWidget(self.delete_button)
        
        list_layout.addLayout(title_layout)
        
        # 数据表格
        self.oob_table = QTableWidget()
        self.oob_table.setColumnCount(6)
        self.oob_table.setHorizontalHeaderLabels([
            "带外管理ID", "设备资产", "设备类型", "登录URL", "带外类型", "IP数量"
        ])
        
        # 设置表格属性
        header = self.oob_table.horizontalHeader()
        header.setSectionResizeMode(0, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(1, QHeaderView.Stretch)
        header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(3, QHeaderView.Stretch)
        header.setSectionResizeMode(4, QHeaderView.ResizeToContents)
        header.setSectionResizeMode(5, QHeaderView.ResizeToContents)
        
        self.oob_table.setSelectionBehavior(QTableWidget.SelectRows)
        self.oob_table.setSelectionMode(QTableWidget.SingleSelection)
        self.oob_table.setAlternatingRowColors(True)
        
        # 连接信号
        self.oob_table.itemSelectionChanged.connect(self.on_selection_changed)
        self.oob_table.itemDoubleClicked.connect(self.edit_oob)
        
        list_layout.addWidget(self.oob_table)
        
        return list_widget
    
    def create_detail_widget(self):
        """创建详情面板组件"""
        detail_widget = QWidget()
        detail_layout = QVBoxLayout(detail_widget)
        detail_layout.setContentsMargins(0, 0, 0, 0)
        detail_layout.setSpacing(10)
        
        # 标题
        detail_title = QLabel("详细信息")
        detail_font = QFont()
        detail_font.setBold(True)
        detail_font.setPointSize(12)
        detail_title.setFont(detail_font)
        detail_layout.addWidget(detail_title)
        
        # 标签页
        self.detail_tabs = QTabWidget()
        
        # 基本信息标签页
        basic_widget = QWidget()
        basic_layout = QVBoxLayout(basic_widget)
        
        self.basic_info_text = QTextEdit()
        self.basic_info_text.setReadOnly(True)
        self.basic_info_text.setMaximumHeight(200)
        basic_layout.addWidget(self.basic_info_text)
        
        self.detail_tabs.addTab(basic_widget, "基本信息")
        
        # 关联信息标签页
        relation_widget = QWidget()
        relation_layout = QVBoxLayout(relation_widget)
        
        self.relation_info_text = QTextEdit()
        self.relation_info_text.setReadOnly(True)
        relation_layout.addWidget(self.relation_info_text)
        
        self.detail_tabs.addTab(relation_widget, "关联信息")
        
        detail_layout.addWidget(self.detail_tabs)
        
        return detail_widget
    
    def on_filter_changed(self):
        """筛选条件改变事件"""
        filter_type = self.filter_combo.currentText()
        self.filter_value_combo.clear()
        
        if filter_type == "全部":
            self.filter_value_combo.addItem("全部")
        elif filter_type == "带外类型":
            self.filter_value_combo.addItems([
                "全部", "iDRAC", "iLO", "IMM", "IPMI", "KVM", "未知类型"
            ])
        elif filter_type == "设备资产":
            # 获取设备资产列表
            try:
                assets = self.oob_service.get_asset_without_oob()
                self.filter_value_combo.addItem("全部")
                for asset in assets:
                    display_text = f"{asset['asset_id']} - {asset['name']}"
                    self.filter_value_combo.addItem(display_text, asset['asset_id'])
            except Exception as e:
                logger.error(f"获取设备资产列表失败: {str(e)}")
                self.filter_value_combo.addItem("全部")
        else:
            self.filter_value_combo.addItem("请输入筛选值...")
        
        self.apply_filter()
    
    def apply_filter(self):
        """应用筛选条件"""
        self.load_oobs()
    
    def on_search_changed(self):
        """搜索条件改变事件"""
        # 使用定时器延迟搜索，避免频繁查询
        if hasattr(self, 'search_timer'):
            self.search_timer.stop()
        
        self.search_timer = QTimer()
        self.search_timer.setSingleShot(True)
        self.search_timer.timeout.connect(self.load_oobs)
        self.search_timer.start(500)  # 500ms后执行搜索
    
    def load_oobs(self):
        """加载带外管理列表"""
        try:
            # 获取筛选条件
            filter_type = self.filter_combo.currentText()
            filter_value = self.filter_value_combo.currentText()
            search_text = self.search_edit.text().strip()
            
            # 转换筛选类型
            filter_mapping = {
                "带外类型": "oob_type",
                "设备资产": "asset_id",
                "登录URL": "login_url"
            }
            
            filter_param = filter_mapping.get(filter_type)
            if filter_value == "全部":
                filter_value = ""
            
            # 获取设备资产ID（如果筛选设备资产）
            if filter_type == "设备资产" and filter_value:
                # 从显示文本中提取asset_id
                if " - " in filter_value:
                    filter_value = filter_value.split(" - ")[0]
            
            # 调用服务获取数据
            result = self.oob_service.get_oob_list(
                filter_type=filter_param,
                filter_value=filter_value,
                search_text=search_text if search_text else None
            )
            
            if result['success']:
                self.current_oobs = result['data']
                self.populate_table()
                self.status_message.emit(f"成功加载 {len(self.current_oobs)} 条带外管理记录")
                self._load_retry_count = 0  # 重置重试计数器
            else:
                QMessageBox.warning(self, "警告", result['message'])
                
        except Exception as e:
            logger.error(f"加载带外管理列表失败: {str(e)}")
            self._load_retry_count += 1
            if self._load_retry_count <= self._max_retries:
                self.status_message.emit(f"加载失败，正在重试 ({self._load_retry_count}/{self._max_retries})...")
                # 延迟重试
                QTimer.singleShot(1000, self.load_oobs)
            else:
                self.status_message.emit("加载失败，请检查数据库连接")
                QMessageBox.critical(self, "错误", f"加载带外管理列表失败: {str(e)}")
    
    def populate_table(self):
        """填充表格数据"""
        self.oob_table.setRowCount(len(self.current_oobs))
        
        for row, oob in enumerate(self.current_oobs):
            # 带外管理ID
            self.oob_table.setItem(row, 0, QTableWidgetItem(oob.get('oob_id', '')))
            
            # 设备资产
            asset_name = oob.get('asset_name', '')
            if not asset_name:
                asset_name = oob.get('asset_id', '')
            self.oob_table.setItem(row, 1, QTableWidgetItem(asset_name))
            
            # 设备类型
            self.oob_table.setItem(row, 2, QTableWidgetItem(oob.get('asset_type', '')))
            
            # 登录URL
            self.oob_table.setItem(row, 3, QTableWidgetItem(oob.get('login_url', '')))
            
            # 带外类型
            login_url = oob.get('login_url', '')
            oob_type = self.oob_utils.get_oob_type_from_url(login_url)
            self.oob_table.setItem(row, 4, QTableWidgetItem(oob_type))
            
            # IP数量
            ip_count = str(oob.get('ip_count', 0))
            self.oob_table.setItem(row, 5, QTableWidgetItem(ip_count))
    
    def on_selection_changed(self):
        """选择改变事件"""
        selected_items = self.oob_table.selectedItems()
        has_selection = len(selected_items) > 0
        
        self.edit_button.setEnabled(has_selection)
        self.delete_button.setEnabled(has_selection)
        
        if has_selection:
            row = selected_items[0].row()
            oob = self.current_oobs[row]
            self.show_oob_details(oob)
        else:
            self.clear_details()
    
    def show_oob_details(self, oob):
        """显示带外管理详情"""
        # 基本信息
        basic_info = f"""带外管理ID: {oob.get('oob_id', 'N/A')}
设备资产ID: {oob.get('asset_id', 'N/A')}
设备名称: {oob.get('asset_name', 'N/A')}
设备类型: {oob.get('asset_type', 'N/A')}
登录URL: {oob.get('login_url', 'N/A')}
带外类型: {self.oob_utils.get_oob_type_from_url(oob.get('login_url', ''))}
创建时间: {oob.get('create_time', 'N/A')}
更新时间: {oob.get('update_time', 'N/A')}"""
        
        self.basic_info_text.setPlainText(basic_info)
        
        # 关联信息
        relation_info = f"""IP地址数量: {oob.get('ip_count', 0)}
关联状态: {'已绑定IP' if oob.get('ip_count', 0) > 0 else '未绑定IP'}
设备状态: 正常"""
        
        self.relation_info_text.setPlainText(relation_info)
    
    def clear_details(self):
        """清空详情信息"""
        self.basic_info_text.clear()
        self.relation_info_text.clear()
    
    def refresh_statistics(self):
        """刷新统计信息"""
        try:
            stats = self.oob_service.get_statistics()
            
            self.total_count_label.setText(str(stats.get('total_count', 0)))
            self.idrac_count_label.setText(str(stats.get('type_distribution', {}).get('iDRAC', 0)))
            self.ilo_count_label.setText(str(stats.get('type_distribution', {}).get('iLO', 0)))
            
            # 计算其他类型数量
            other_count = stats.get('total_count', 0) - stats.get('type_distribution', {}).get('iDRAC', 0) - stats.get('type_distribution', {}).get('iLO', 0)
            self.other_count_label.setText(str(other_count))
            
            self.ip_binding_count_label.setText(str(stats.get('ip_binding_count', 0)))
            
        except Exception as e:
            logger.error(f"刷新统计信息失败: {str(e)}")
    
    def add_oob(self):
        """新增带外管理"""
        dialog = OobDialog(self)
        dialog.data_saved.connect(self.on_oob_saved)
        dialog.exec_()
    
    def edit_oob(self):
        """编辑带外管理"""
        selected_items = self.oob_table.selectedItems()
        if not selected_items:
            return
        
        row = selected_items[0].row()
        oob = self.current_oobs[row]
        oob_id = oob.get('oob_id')
        
        dialog = OobDialog(self, oob_id)
        dialog.data_saved.connect(self.on_oob_saved)
        dialog.exec_()
    
    def delete_oob(self):
        """删除带外管理"""
        selected_items = self.oob_table.selectedItems()
        if not selected_items:
            return
        
        row = selected_items[0].row()
        oob = self.current_oobs[row]
        oob_id = oob.get('oob_id')
        
        # 确认删除
        reply = QMessageBox.question(
            self, "确认删除",
            f"确定要删除带外管理 {oob_id} 吗？\n\n注意：如果该带外管理下有IP地址绑定，将无法删除。",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            try:
                result = self.oob_service.delete_oob(oob_id)
                if result['success']:
                    QMessageBox.information(self, "成功", result['message'])
                    self.load_oobs()
                    self.refresh_statistics()
                else:
                    QMessageBox.warning(self, "警告", result['message'])
            except Exception as e:
                logger.error(f"删除带外管理失败: {str(e)}")
                QMessageBox.critical(self, "错误", f"删除失败: {str(e)}")
    
    def on_oob_saved(self, data):
        """带外管理保存成功事件"""
        self.load_oobs()
        self.refresh_statistics()
        self.status_message.emit("带外管理保存成功")
    
    def export_data(self):
        """导出数据"""
        try:
            # 导出当前筛选的数据
            oob_ids = [oob.get('oob_id') for oob in self.current_oobs]
            
            if not oob_ids:
                QMessageBox.information(self, "提示", "没有数据可导出")
                return
            
            export_data = self.oob_service.export_oob_data(oob_ids)
            
            # 这里可以实现导出到Excel的功能
            # 暂时显示导出成功消息
            QMessageBox.information(self, "成功", f"成功导出 {len(export_data)} 条记录")
            
        except Exception as e:
            logger.error(f"导出数据失败: {str(e)}")
            QMessageBox.critical(self, "错误", f"导出失败: {str(e)}")